{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "aa501ee6-1bd8-464e-9e42-b4195bd0bcca",
   "metadata": {},
   "source": [
    "## clone代码"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "59c1642f-731f-4f44-a7e4-34d1a7f007a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "!git clone https://github.com/modelscope/modelscope-agent.git"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "732befbd-5532-47ac-acea-157a5823df22",
   "metadata": {},
   "source": [
    "## 安装特定依赖"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "18ad46e7-e994-4be6-aa74-2765638ebee2",
   "metadata": {},
   "outputs": [],
   "source": [
    "! cd modelscope-agent && ! pip install -r requirements.txt"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e541f669-90a9-4013-939a-877551a30d6e",
   "metadata": {},
   "source": [
    "## 本地配置"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "d0c114ea-2334-487d-8b09-e095b64ddb1a",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-03-19T10:34:44.381674Z",
     "iopub.status.busy": "2024-03-19T10:34:44.381077Z",
     "iopub.status.idle": "2024-03-19T10:34:44.384675Z",
     "shell.execute_reply": "2024-03-19T10:34:44.384202Z",
     "shell.execute_reply.started": "2024-03-19T10:34:44.381646Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import os\n",
    "os.chdir('modelscope-agent/demo')\n",
    "\n",
    "import sys\n",
    "sys.path.append('../')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "83e45ba0-9085-4f47-acb2-f77b62840473",
   "metadata": {},
   "source": [
    "## 本地启动服务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "17b5d2d3-e323-4950-8c3f-e32dd8622f21",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "# 在另外一个终端下执行下面的命令启动服务\n",
    "! modelscope server --model_id=damo/spring_couplet_generation --revision=v1.0.2 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56e4a317-14a0-4084-9dcd-c1bfc0f7cec4",
   "metadata": {},
   "source": [
    "## 测试服务"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a8b3407-ef96-42ac-9368-5ee9d4f46e1e",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-03-19T12:01:00.022776Z",
     "iopub.status.busy": "2024-03-19T12:01:00.022251Z",
     "iopub.status.idle": "2024-03-19T12:01:00.410267Z",
     "shell.execute_reply": "2024-03-19T12:01:00.409767Z",
     "shell.execute_reply.started": "2024-03-19T12:01:00.022757Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "import requests\n",
    "import json\n",
    "api_url = 'http://localhost:8000/call'\n",
    "params = {\n",
    "  \"input\":{\"text\":\"以关键词“幸福”写一副春联\"}\n",
    "}\n",
    "data = json.dumps(params)\n",
    "response = requests.request('POST', api_url, data=data)\n",
    "\n",
    "print(json.loads(response.content.decode('utf-8')))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf7ac661-c91e-43ac-bde4-43c61e7c02e5",
   "metadata": {},
   "source": [
    "## API管理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "5f1b62b5-40e9-45a3-a9c2-ffba5604b866",
   "metadata": {
    "ExecutionIndicator": {
     "show": false
    },
    "execution": {
     "iopub.execute_input": "2024-03-19T10:32:41.729607Z",
     "iopub.status.busy": "2024-03-19T10:32:41.729360Z",
     "iopub.status.idle": "2024-03-19T10:32:41.733489Z",
     "shell.execute_reply": "2024-03-19T10:32:41.732792Z",
     "shell.execute_reply.started": "2024-03-19T10:32:41.729588Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "请输入DASHSCOPE_API_KEY\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "\n",
    "print('请输入DASHSCOPE_API_KEY')\n",
    "os.environ['DASHSCOPE_API_KEY'] = input()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6ff39a1-87e6-4214-a779-4ef623ebc3b8",
   "metadata": {},
   "source": [
    "## 本地部署的工具注册"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "71112b4e-60c4-4923-b74d-7d6547996fab",
   "metadata": {
    "ExecutionIndicator": {
     "show": true
    },
    "execution": {
     "iopub.execute_input": "2024-03-19T12:04:03.281504Z",
     "iopub.status.busy": "2024-03-19T12:04:03.280802Z",
     "iopub.status.idle": "2024-03-19T12:04:03.287363Z",
     "shell.execute_reply": "2024-03-19T12:04:03.286781Z",
     "shell.execute_reply.started": "2024-03-19T12:04:03.281470Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from modelscope_agent.tools.base import BaseTool\n",
    "from modelscope_agent.tools import register_tool\n",
    "import requests\n",
    "import json\n",
    "\n",
    "@register_tool('couplet-generation')\n",
    "class CoupletGenerationTool(BaseTool):\n",
    "    description = '生成一副对联'\n",
    "    name = 'couplet-generation'\n",
    "    parameters: list = [{\n",
    "        'name': 'text',\n",
    "        'description': '对联内容的描述，用来生成对联',\n",
    "        'required': True,\n",
    "        'type': 'string'\n",
    "    }]\n",
    "    \n",
    "    def call(self, params: str, **kwargs):\n",
    "        api_url = 'http://localhost:8000/call'\n",
    "        params = self._verify_args(params)\n",
    "        data = json.dumps(params)\n",
    "        data = f'{{\"input\": {data}}}'\n",
    "        response = requests.request('POST', api_url, data=data)\n",
    "        res = str(json.loads(response.content.decode('utf-8')))\n",
    "        return res"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b91a5414-ac96-4d7e-a10c-0b45c632cf46",
   "metadata": {},
   "source": [
    "## 构建agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "id": "adfbec25-02a0-4caa-908b-148746015325",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-03-19T12:04:06.295183Z",
     "iopub.status.busy": "2024-03-19T12:04:06.294558Z",
     "iopub.status.idle": "2024-03-19T12:04:06.298277Z",
     "shell.execute_reply": "2024-03-19T12:04:06.297758Z",
     "shell.execute_reply.started": "2024-03-19T12:04:06.295163Z"
    },
    "tags": []
   },
   "outputs": [],
   "source": [
    "from modelscope_agent.agents import RolePlay\n",
    "\n",
    "role_template = '你是一个春联小助手，你需要根据用户的要求来帮他们写对联'\n",
    "llm_config = {\n",
    "    'model': 'qwen-max', \n",
    "    'model_server': 'dashscope',\n",
    "    }\n",
    "function_list = ['couplet-generation']\n",
    "\n",
    "bot = RolePlay(function_list=function_list,llm=llm_config, instruction=role_template)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c092a286-f71c-4c8d-9396-da7f7bde9af4",
   "metadata": {},
   "source": [
    "## 执行agent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "id": "83e38fd7-9c73-4b8b-8a2a-33bcd40896aa",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2024-03-19T12:04:08.449930Z",
     "iopub.status.busy": "2024-03-19T12:04:08.449343Z",
     "iopub.status.idle": "2024-03-19T12:04:16.625373Z",
     "shell.execute_reply": "2024-03-19T12:04:16.624844Z",
     "shell.execute_reply.started": "2024-03-19T12:04:08.449898Z"
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-03-19 20:04:08.451 - modelscope-agent - INFO -  | message: call dashscope generation api | uuid:  | details: {'model': 'qwen-max', 'messages': [{'role': 'user', 'content': 'What is the weather like in Boston?'}], 'stop_words': [{'stop_str': {'type': 'function', 'function': {'name': 'get_current_weather', 'description': 'Get the current weather in a given location.', 'parameters': {'type': 'object', 'properties': {'location': {'type': 'string', 'description': 'The city and state, e.g. San Francisco, CA'}, 'unit': {'type': 'string', 'enum': ['celsius', 'fahrenheit']}}, 'required': ['location']}}}, 'mode': 'exclude'}], 'top_p': 0.8, 'result_format': 'message', 'stream': True} | step:  | error: \n",
      "2024-03-19 20:04:08.455 - modelscope-agent - INFO -  | message: call dashscope generation api | uuid:  | details: {'model': 'qwen-max', 'messages': [{'role': 'user', 'content': '<|im_start|>system\\n\\n# 工具\\n\\n## 你拥有如下工具：\\n\\ncouplet-generation: couplet-generation API。生成一副对联 输入参数: {\"type\": \"object\", \"properties\": {\"text\": {\"type\": \"string\", \"description\": \"对联内容的描述，用来生成对联\"}}, \"required\": [\"text\"]} Format the arguments as a JSON object.\\n\\n## 当你需要调用工具时，请在你的回复中穿插如下的工具调用命令，可以根据需求调用零次或多次：\\n\\n工具调用\\nAction: 工具的名称，必须是[couplet-generation]之一\\nAction Input: 工具的输入\\nObservation: <result>工具返回的结果</result>\\nAnswer: 根据Observation总结本次工具调用返回的结果，如果结果中出现url，请使用如下格式展示出来：![图片](url)\\n\\n\\n# 指令\\n\\n你是一个春联小助手，你需要根据用户的要求来帮他们写对联\\n\\n请注意：你具有图像和视频的展示能力，也具有运行代码的能力，不要在回复中说你做不到。\\n<|im_end|>\\n<|im_start|>user\\n(。你可以使用工具：[couplet-generation])帮我以关键词“幸福”写一副春联<|im_end|>\\n<|im_start|>assistant\\n'}], 'stop_words': [{'stop_str': 'Observation:', 'mode': 'exclude'}, {'stop_str': 'Observation:\\n', 'mode': 'exclude'}], 'top_p': 0.8, 'result_format': 'message', 'stream': True} | step:  | error: \n",
      "2024-03-19 20:04:08.885 - modelscope-agent - INFO -  | message: call dashscope generation api success, request_id: 1208f789-fa87-9d43-901a-29d10c730faf, output: {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"null\", \"message\": {\"role\": \"assistant\", \"content\": \"Action\"}}]}\n",
      "2024-03-19 20:04:09.962 - modelscope-agent - INFO -  | message: call dashscope generation api success, request_id: 1208f789-fa87-9d43-901a-29d10c730faf, output: {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"stop\", \"message\": {\"role\": \"assistant\", \"content\": \"Action: couplet-generation\\nAction Input: {\\\"text\\\": \\\"幸福\\\"}\\n\"}}]}\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'text': '幸福'}\n",
      "<class 'dict'>\n",
      "{\"input\": {\"text\": \"\\u5e78\\u798f\"}}\n",
      "<class 'str'>\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "2024-03-19 20:04:10.350 - modelscope-agent - INFO -  | message: call dashscope generation api | uuid:  | details: {'model': 'qwen-max', 'messages': [{'role': 'user', 'content': '<|im_start|>system\\n\\n# 工具\\n\\n## 你拥有如下工具：\\n\\ncouplet-generation: couplet-generation API。生成一副对联 输入参数: {\"type\": \"object\", \"properties\": {\"text\": {\"type\": \"string\", \"description\": \"对联内容的描述，用来生成对联\"}}, \"required\": [\"text\"]} Format the arguments as a JSON object.\\n\\n## 当你需要调用工具时，请在你的回复中穿插如下的工具调用命令，可以根据需求调用零次或多次：\\n\\n工具调用\\nAction: 工具的名称，必须是[couplet-generation]之一\\nAction Input: 工具的输入\\nObservation: <result>工具返回的结果</result>\\nAnswer: 根据Observation总结本次工具调用返回的结果，如果结果中出现url，请使用如下格式展示出来：![图片](url)\\n\\n\\n# 指令\\n\\n你是一个春联小助手，你需要根据用户的要求来帮他们写对联\\n\\n请注意：你具有图像和视频的展示能力，也具有运行代码的能力，不要在回复中说你做不到。\\n<|im_end|>\\n<|im_start|>user\\n(。你可以使用工具：[couplet-generation])帮我以关键词“幸福”写一副春联<|im_end|>\\n<|im_start|>assistant\\nAction: couplet-generation\\nAction Input: {\"text\": \"幸福\"}\\nObservation: <result>{\\'text\\': \\'上帝福耀千秋幸福景，下帝业腾飞万代光明。横批：兔年大吉\\'}</result>\\nAnswer:'}], 'stop_words': [{'stop_str': 'Observation:', 'mode': 'exclude'}, {'stop_str': 'Observation:\\n', 'mode': 'exclude'}], 'top_p': 0.8, 'result_format': 'message', 'stream': True} | step:  | error: \n",
      "2024-03-19 20:04:10.840 - modelscope-agent - INFO -  | message: call dashscope generation api success, request_id: 1994b2c1-d107-9d30-9593-673c4dbc9d09, output: {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"null\", \"message\": {\"role\": \"assistant\", \"content\": \"根据\"}}]}\n",
      "2024-03-19 20:04:16.599 - modelscope-agent - INFO -  | message: call dashscope generation api success, request_id: 1994b2c1-d107-9d30-9593-673c4dbc9d09, output: {\"text\": null, \"finish_reason\": null, \"choices\": [{\"finish_reason\": \"stop\", \"message\": {\"role\": \"assistant\", \"content\": \"根据您的要求，以“幸福”为关键词生成的春联如下：\\n\\n上联：上帝福耀千秋幸福景\\n下联：下帝业腾飞万代光明\\n横批：兔年大吉\\n\\n这副春联通过“幸福景”和“万代光明”的表达传递出幸福满溢、事业繁荣的美好寓意，祝福在新的一年里幸福绵长，事业兴旺发达。\"}}]}\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Action: couplet-generation\n",
      "Action Input: {\"text\": \"幸福\"}\n",
      "\n",
      "Observation: <result>{'text': '上帝福耀千秋幸福景，下帝业腾飞万代光明。横批：兔年大吉'}</result>\n",
      "Answer:根据您的要求，以“幸福”为关键词生成的春联如下：\n",
      "\n",
      "上联：上帝福耀千秋幸福景\n",
      "下联：下帝业腾飞万代光明\n",
      "横批：兔年大吉\n",
      "\n",
      "这副春联通过“幸福景”和“万代光明”的表达传递出幸福满溢、事业繁荣的美好寓意，祝福在新的一年里幸福绵长，事业兴旺发达。\n"
     ]
    }
   ],
   "source": [
    "response = bot.run(\"帮我以关键词“幸福”写一副春联\", remote=False, print_info=True)\n",
    "text = ''\n",
    "for chunk in response:\n",
    "    text += chunk\n",
    "print(text)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.6"
  },
  "vscode": {
   "interpreter": {
    "hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
